package exabase.data;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Set;
import java.util.logging.Logger;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class DataPersistence {
	private static Logger logger = Logger.getLogger(DataPersistence.class
			.getName());

	private static DataPersistence instance = null;

	protected DataPersistence() {
		// Exists only to defeat instantiation.
	}

	public static DataPersistence getInstance() {
		if (instance == null) {
			instance = new DataPersistence();
		}
		return instance;
	}

	public void getDataFrom(String fileName) {
		logger.fine("reading data from " + fileName);
		JAXBContext ctx;
		try {
			ctx = JAXBContext
					.newInstance(new Class[] { exabase.auto.data.DataStore.class });
			Unmarshaller um;
			um = ctx.createUnmarshaller();
			exabase.auto.data.DataStore autoDataStore = (exabase.auto.data.DataStore) um
					.unmarshal(new File(fileName));
			putDataToDataStore(autoDataStore);
		} catch (JAXBException e) {
			logger.severe("failed reading data from " + fileName);
		}
	}

	protected void putDataToDataStore(exabase.auto.data.DataStore autoDataStore) {
		for (exabase.auto.data.DataStore.Data data : autoDataStore.getData())
			DataStore.getInstance().addData(data.getFileURL(),
					new Hash(data.getHash()));
	}

	protected exabase.auto.data.DataStore getDataFromDataStore() {
		Set<Data> dataSet = DataStore.getInstance().getDataSet();
		exabase.auto.data.DataStore autoDataStore = new exabase.auto.data.DataStore();
		for (Data data : dataSet) {
			exabase.auto.data.DataStore.Data autoData = new exabase.auto.data.DataStore.Data();
			autoData.setFileURL(data.getFileURL());
			autoData.setHash(data.getHash().toString());
			autoDataStore.getData().add(autoData);
		}
		return autoDataStore;
	}

	public void putDataTo(String fileName) {
		logger.fine("writing data to " + fileName);
		try {
			JAXBContext jc = JAXBContext
					.newInstance(exabase.auto.data.DataStore.class);
			Marshaller m = jc.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
			m.marshal(getDataFromDataStore(), new FileOutputStream(fileName));
		} catch (FileNotFoundException e) {
			logger.severe("failed writing data to " + fileName
					+ ". reason: file not found");
		} catch (JAXBException e) {
			logger.severe("failed writing data to " + fileName);
		}
	}

}
